'nodejs';


require('rhino').install();
const { viewFile } = require('app');
const { defaultThemeContext } = require('ui');
const FloatMenu = require('..');
const AnimationFloat = require('../modules/animation_foat');
const { defineValue, createShape, dp2px } = require('../modules/__util__');

const Color = android.graphics.Color;
const ColorUtils = Packages.androidx.core.graphics.ColorUtils;
const JsImageView = com.stardust.autojs.core.ui.widget.JsImageView;

const onClickListener = Symbol();
const scale = Symbol();
const icons = Symbol();
const tints = Symbol();
const colors = Symbol();
const style = Symbol();
const checked = Symbol();
const float_menu = Symbol();

class ItemView extends JsImageView {

    /**
     * 自定义控件 ItemView
     * @param {FloatMenu} fm
     * @param {string} name 控件名称
     */
    constructor(fm, name) {
        super(defaultThemeContext());
        this[float_menu] = fm;
        /** 控件名称 */
        this.name = name;
        /** @type {AnimationFloat} */
        this.animator = null;
        this.scaleView = true;
        init(this);
    }

    /**
     * 按钮控件样式 
     */
    static TYPE_ITEM_STYLE_BUTTON = 0;
    /**
     * 复选框控件样式
     */
    static TYPE_ITEM_STYLE_CHECKBOX = 1;

    /**
     * @callback ItemViewOnClickCallback
     * @param {ItemView} view
     * @returns {boolean=} 是否关闭菜单 没有返回值或者返回true保持菜单开启,返回false关闭菜单
     */

    /**
     * 控件点击事件
     * @param {ItemViewOnClickCallback} callback 
     * @returns 
     */
    onClick(callback) {
        if ('function' === typeof callback)
            this[onClickListener] = callback;
        return this;
    }

    /**
     * 设置控件图标组
     * @param {colorstr} uri 
     * @returns 
     */
    setIcons(uri) {
        this[icons] = Array.prototype.slice.call(arguments);
        return this;
    }

    /**
     * 设置控件图标颜色组
     * @param {string} colorstr 
     */
    setTints(colorstr) {
        this[tints] = Array.prototype.slice.call(arguments);
        return this;
    }

    /**
     * 设置控件背景色组
     * @param {string} colorstr 字符串颜色
     */
    setColors(colorstr) {
        this[colors] = Array.prototype.slice.call(arguments);
        return this;
    }

    /**
     * 设置控件大小
     * @param {numbar} dp 
     */
    setSize(dp) {
        this.attr('w', `${dp}dp`);
        this.attr('h', `${dp}dp`);
        return this;
    }

    /**
     * 设置控件背景圆角
     * @param {number} dp 
     */
    setRadius(dp) {
        let px = dp2px(dp);
        this.getBackground().setCornerRadius(px);
        return this;
    }

    /**
     * 设置边框描边
     * @param {number} width 画笔宽度
     * @param {string} color 画笔颜色
     * @param {number} width 虚线线宽
     * @param {number} width 虚线隔宽
     */
    setStroke(width = 0, color = '#000000', dashWidth = 0, dashGap = 0) {
        this.getBackground().setStroke(width, Color.parseColor(color), dashWidth, dashGap);
        return this;
    }

    /**
     * 设置控件内边距
     * @param {numbar} dp 
     */
    setPaddings(dp) {
        let px = dp2px(dp);
        this.setPadding(px, px, px, px);
        return this;
    }

    /**
     * 设置控件样式
     * 
     *      //设置控件为按钮样式
     *      fm.addItem('按钮1').setStyle(FloatMenu.TYPE_ITEM_STYLE_BUTTON);
     *      //设置控件为复选框样式
     *      fm.addItem('复选框按钮1').setStyle(FloatMenu.TYPE_ITEM_STYLE_CHECKBOX);
     * @param {number} value 
     * @returns 
     */
    setStyle(value) {
        this[style] = value;
        return this;
    }

    /**
     * 设置控件缩放参数 默认0.8
     * @param {number} value
     */
    setAnimScaleValue(value) {
        this[scale] = value;
        return this;
    }

    /**
     * 执行点击动画时是否缩放控件
     * @param {boolean} isScale 
     */
    setAnimScaleView(isScale) {
        this.scaleView = isScale;
    }

    /**
     * 设置控件是否选中 (当控件为复选框样式时才能生效)
     * @param {boolean} value 
     * @returns 
     */
    setChecked(value) {
        if (this.checked !== null) {
            this[checked] = !!value;
        }
        return this;
    }

    get checked() {
        return this[checked];
    }

    /**
     * 获取控件是否选中
     * @returns {boolean|null}
     */
    getChecked() {
        return this.checked;
    }

}

/**
 * @param {ItemView} scope 
 */
function init(scope) {

    defineValue(scope, 'style', ItemView.TYPE_ITEM_STYLE_BUTTON, style => {
        switch (style) {
            case ItemView.TYPE_ITEM_STYLE_BUTTON:
                scope[checked] = null;
                break;
            case ItemView.TYPE_ITEM_STYLE_CHECKBOX:
                scope[checked] = false;
                break;
        }
    });
    defineValue(scope, checked, null, val => {
        scope.emit('click', scope, true);
    });
    defineValue(scope, colors, null, val => {
        scope.color = getValue(scope, colors);
    });
    defineValue(scope, tints, null, val => {
        scope.tint = getValue(scope, tints);
    });
    defineValue(scope, icons, null, val => {
        scope.icon = getValue(scope, icons);
    });
    defineValue(scope, 'color', null, val => {
        if ('string' === typeof val) {
            val = Color.parseColor(val);
        }
        scope.getBackground().setColor(val);
    });
    defineValue(scope, 'tint', null, val => {
        if ('number' === typeof val)
            val = Color.toString(val);
        scope.attr('tint', val);
    });
    defineValue(scope, 'icon', null, val => {
        scope.attr('src', val);
    });

    //init config
    let size = dp2px(scope[float_menu].config.all_item_size);
    //layoutparams
    let params = new android.widget.FrameLayout.LayoutParams(size, size);
    scope.setLayoutParams(params);
    //内边距
    let padding = scope[float_menu].config.all_item_padding;
    scope.setPaddings(padding);
    //background
    let gd = createShape(scope[float_menu].config.all_item_radius, null, null);
    scope.setBackground(gd);
    //裁剪视图
    scope.setClipToOutline(true);
    scope.setClickable(true);
    //点击水波纹效果
    scope.attr('foreground', '?attr/selectableItemBackground');
    //缩放参数
    scope[scale] = scope[float_menu].config.menu_item_scale;
    //点击事件
    scope.on('click', function (v, isChecked) {
        let result = true;
        if (scope.checked !== null && !isChecked)
            return scope[checked] = !scope[checked];
        if (scope[onClickListener]) {
            result = scope[onClickListener](scope, scope.checked);
        } else {
            let listeners = scope[float_menu].emitter._events.item_click;
            if (listeners) {
                if (!Array.isArray(listeners)) {
                    listeners = [listeners];
                }
                result = listeners.reduce((res, listener) => {
                    result = listener(scope, scope.checked);
                    if (res === false)
                        return res;
                    else
                        return result;
                }, result);
            }
        }
        scope.animator.start();
        if (result === false)
            scope[float_menu].setState(1);
    });
    //处理用户误加click事件
    let emitter_on = scope.on;
    scope.on = function (type, callback) {
        if (type !== 'click')
            emitter_on.on(type, callback);
    }
    //init animator
    initAnimator(scope);
}

function initOnClick() {

}

/**
 * 控件点击动画
 * @param {ItemView} scope 
 */
function initAnimator(scope) {
    let fm = scope[float_menu];
    let animator = new AnimationFloat(fm, 0, 1, fm.config.animator_duration_item);
    let iicons, itints, icolors, iscale;
    let f, isUpdateIcon;
    animator.onAnimatoinUpdate(animator => {
        f = animator.getAnimatedValue();
        if (scope.checked !== null) {
            if (icolors) //更新背景色
                scope.color = ColorUtils.blendARGB(icolors[0], icolors[1], f);
            if (itints)//更新图标颜色
                scope.tint = ColorUtils.blendARGB(itints[0], itints[1], f);
            if (iicons && !isUpdateIcon && f > .5)//更新图标
                (isUpdateIcon = true, scope.icon = iicons);
        }
        //缩放控件
        if (scope.scaleView) {
            iscale = 1 - Math.abs(Math.abs(.5 - f) - .5) * (1 - scope[scale]);
            scope.setScaleX(iscale);
            scope.setScaleY(iscale);
        }
        scope.emit('animation_update', scope, f);
    })
    animator.onAnimationStart(() => {
        scope.setClickable(false);
        isUpdateIcon = false;
        icolors = getColors(scope, colors);
        itints = getColors(scope, tints);
        iicons = getIcon(scope, icons);
    });
    animator.onAnimationEnd(() => {
        scope.setClickable(true);
    });

    scope.animator = animator;
}

function getValue(view, type) {
    if (Array.isArray(view[type])) {
        return view[type][view.checked ? view[type].length - 1 : 0];
    } else {
        return null;
    }
}

function getColors(view, key) {
    if (!Array.isArray(view[key]) || view[key].length <= 1) return null;
    let [a, b] = view[key];
    a = Color.parseColor(a);
    b = Color.parseColor(b || a);
    if (!view.checked) [a, b] = [b, a];
    return [a, b];
}

function getIcon(view, key) {
    if (!Array.isArray(view[key]) || view[key].length <= 1) return null;
    return view[key][view.checked ? 1 : 0];
}

module.exports = ItemView;